package model;

/**
 * Classe qui représente le terrain d'un joueur.
 *
 * @author Antoine Thorr, Joana Santos, Samy Rida, Vicky Ngo Pagbe
 */
public class PartieTerrain {

    private CarteOffensive[] attaque;
    private CarteDefensive[] defense;
    private Carte[] cartes;
    private final int maxLigneCartes = 5;

    /**
     * Construit le Terrain du joueur. Il créer une liste de 5 cartes Défensives
     * et une autre liste de 5 cartes Offensives.
     */
    public PartieTerrain() {
        this.attaque = new CarteOffensive[this.maxLigneCartes];
        this.defense = new CarteDefensive[this.maxLigneCartes];
        this.cartes = new Carte[this.maxLigneCartes * 2]; //ArrayList de 10, d'abord attaque 0-4 et def 5-9
    }

    /**
     * Retourne un tableau de Carte contenant toutes les cartes offensives
     * présentes sur le terrain du joueur concerné.
     *
     * @return Tableau de Carte.
     */
    public CarteOffensive[] getAttaque() {
        return attaque;
    }

    /**
     * Retourne un tableau de Carte contenant toutes les cartes défensives
     * présentes sur le terrain du joueur concerné.
     *
     * @return Tableau de Carte.
     */
    public CarteDefensive[] getDefense() {
        return defense;
    }

    /**
     * Retourne un tableau de Carte contenant toutes les cartes présente sur le
     * terrain du joueur concerné.
     *
     * @return Tableau de Carte.
     */
    public Carte[] getCartes() {
        return cartes;
    }

    /**
     * Retourne la carte Offensive présente à l'indice passé en paramètre.
     *
     * @param indice
     * @return Carte Offensive
     */
    public CarteOffensive getCarteOffensive(int indice) {
        return this.attaque[indice];
    }

    /**
     * Retourne la carte défensive présente à l'indice passé en paramètre.
     *
     * @param indice
     * @return Carte défensive
     */
    public CarteDefensive getCarteDefensive(int indice) {
        return this.defense[indice];
    }

    /**
     * Retourne la carte présente sur le terrain à l'indice passé en paramètre.
     *
     * @param indice
     * @return Carte présente à l'indice i
     */
    public Carte getCarte(int indice) {
        return this.cartes[indice];
    }

    /**
     * Retourne si l'indice est compris entre 0 et 4.
     *
     * @param indice
   * @return 
     * @returns true si l'indice est compris entre 0 et 4
     */
    public boolean isBounded(int indice) {
        return indice < this.attaque.length && indice >= 0;
    }

    /**
     * Retourne si la case Offensive à l'indice indiqué est déjà prise.
     *
     * @param indice
     * @return True si la case est déjà prise, False sinon.
     */
    public boolean caseDejaPriseOff(int indice) {
        return this.attaque[indice] != null;
    }

    /**
     * Retourne si la case Défensive à l'indice indiqué est déjà prise.
     *
     * @param indice
     * @return True si la case est déjà prise, False sinon.
     */
    public boolean caseDejaPriseDef(int indice) {
        return this.defense[indice] != null;
    }

    /**
     * Permet de placer la Carte Offensive c à la place indice i.
     *
     * @param c : Carte à placer.
     * @param i : Indice où placer la carte.
     */
    public void placerOff(CarteOffensive c, int i) {
        this.attaque[i] = c;
        this.cartes[i] = c;
        c.setEtat(Etat.sleep);
    }

    /**
     * Permet de placer la Carte Défensive c à la place indice i.
     *
     * @param c : Carte à placer.
     * @param i : Indice où placer la carte.
     */
    public void placerDef(CarteDefensive c, int i) {
        this.defense[i] = c;
        this.cartes[this.maxLigneCartes + i] = c;
    }

    /**
     * Retourne le nombre de carte présente sur la ligne d'attaque du joueur
     * concerné.
     *
     * @return le nombre de carte présente sur la ligne d'attaque.
     */
      public int nbAttaque() {
    int compteur = 0;
    for (CarteOffensive co : this.attaque) {
      if (this.attaque[compteur] != null) {
        compteur++;
        //System.out.println("Attaque : compteur="+compteur+", carte="+co.getNom());
      }
    }
    return compteur;
  }

    /**
     * Retourne le nombre de carte présente sur la ligne de défense du joueur
     * concerné.
     *
     * @return le nombre de carte présente sur la ligne de défense.
     */public int nbDefense() {
    int compteur = 0;
    for (CarteDefensive cd : this.defense) {
      if (this.defense[compteur] != null) {
        compteur++;
        //System.out.println("Defense : compteur="+compteur+", carte="+cd.getNom());
      }
    }
    return compteur;
  }

    /**
     * Retourne le nombre total de cartes présentes sur le Terrain du joueur
     * concerné.
     *
     * @return nombre de cartes présentes sur le terrain.
     */
    public int nbTotal() {
        int compteur = 0;
        for (Carte nbTot : this.cartes) {
            if (this.cartes[compteur] != null) {
                compteur++;
            }
        }
        return compteur;
    }

    /**
     * Redéfinition de la méthode toString.
     *
     * @return
     */
    @Override
    public String toString() {
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < getAttaque().length; i++) {
            if (caseDejaPriseOff(i)) {
                str.append(getCarteOffensive(i));
                str.append("/");
            }
        }
        str.append("\n");
        for (int i = 0; i < getAttaque().length; i++) {
            if (caseDejaPriseDef(i)) {
                str.append(getCarteDefensive(i));
                str.append("/");
            }
        }
        return str.toString();
    }

    /**
     * Permet de déselectionner toute les cartes présente sur le terrain.
     */
    public void deselectionner() {
        for (int i = 0; i < this.attaque.length; i++) {
            if (this.caseDejaPriseOff(i)) {
                this.attaque[i].setSelection(false);
            }
        }
        for (int i = 0; i < this.defense.length; i++) {
            if (this.caseDejaPriseDef(i)) {
                this.defense[i].setSelection(false);
            }
        }
    }

    /**
     * Retourne si la carte c passé en paramètre est présente sur le terrain du
     * joueur concerné.
     *
     * @param c Carte à chercher.
     * @return True si la carte est sur le terrain, false sinon.
     */
    public boolean isOnField(Carte c) {
        for (CarteOffensive co : this.attaque) {
            if (co == c) {
                return true;
            }
        }
        for (CarteDefensive cd : this.defense) {
            if (cd == c) {
                return true;
            }
        }
        return false;
    }

    /**
     * Retourne le nombre maximum de ligne présente sur le Terrain pour chaque
     * type de carte.
     *
     * @return nombre d elignes maximum.
     */
    public int getMaxLigneCartes() {
        return this.maxLigneCartes;
    }
}
